package com.hwx.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import io.micrometer.core.instrument.util.StringUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Component
public class TokenFilter extends ZuulFilter {

    @Override
    public Object run() throws ZuulException {
        // 获取上下文
         RequestContext currentContext = RequestContext.getCurrentContext();
         HttpServletRequest request = currentContext.getRequest();
         //从请求头里获取token对象
         String userToken = request.getHeader("userToken");
         //从请求参数里获取token对象
         if(StringUtils.isBlank((userToken))){
             userToken = request.getParameter("userToken");
         }

        //登录校验逻辑 根据公司情况自定义
         if (StringUtils.isEmpty(userToken)) {
             currentContext.setSendZuulResponse(false);
             currentContext.setResponseStatusCode(401);
             currentContext.setResponseBody("userToken is null");
             return null;
         }
         // 否则正常执行业务逻辑.....
         return null;
       }

     // 过滤器类型
     @Override
     public String filterType() {
        // 1）pre 可以在请求被路由之前调用。适用于身份认证的场景，认证通过后再继续执行下面的流程。
        // 2）post 在 route 和 error 过滤器之后被调用。这种过滤器将请求路由到达具体的服务之后执行。适用于需要添加响应头，记录响应日志等应用场景。
        // 3）route 在路由请求时被调用。适用于灰度发布场景，在将要路由的时候可以做一些自定义的逻辑。
        // 4）error 处理请求时发生错误时被调用。在执行过程中发送错误时会进入 error 过滤器，可以用来统一记录错误信息。
         return "pre";
       }

    @Override
    public boolean shouldFilter() {
        // 是否执行该过滤器，true 为执行，false 为不执行，这个也可以利用配置中心来实现，达到动态的开启和关闭过滤器。
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        if ("/haochen/member/login".equalsIgnoreCase(request.getRequestURI())){
            return false;
        }
        return true;
    }

    // 过滤器的执行顺序，数值越小，优先级越高。
    @Override
    public int filterOrder() {
        // 过滤器的执行顺序，数值越小，优先级越高。
        return 0;
    }

}
